/*
 * Copyright (c) 2020. André Mion
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.andremion.louvre.home;

import com.andremion.louvre.CheckRadioView;
import com.andremion.louvre.ResourceTable;
import com.andremion.louvre.loader.LoaderCallback;
import com.andremion.louvre.loader.ResultSetLoader;
import com.andremion.louvre.preview.PreviewActivity;
import com.andremion.louvre.util.Utils;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.StackLayout;
import ohos.agp.components.BaseItemProvider;
import ohos.agp.components.ListContainer;
import ohos.agp.components.TableLayoutManager;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;
import ohos.data.resultset.ResultSet;
import ohos.media.photokit.metadata.AVStorage;
import ohos.utils.net.Uri;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import static com.andremion.louvre.Louvre.*;
import static com.andremion.louvre.StoragePermissionActivity.RESULT_OK;

public class GalleryFragment extends Ability {
    /**
     * Start the Gallery Fragment with additional launch information.
     *
     * @param activity        Context to launch activity from.
     * @param requestCode     If >= 0, this code will be returned in onActivityResult() when the activity exits.
     * @param maxSelection    The max count of image selection
     * @param selection       The current image selection
     * @param mediaTypeFilter The media types that will display
     * @param mThemeColor     Color
     */
    public static void startActivity(Ability activity, int requestCode,
                                     int mThemeColor,
                                     int maxSelection,
                                     List<Uri> selection,
                                     String... mediaTypeFilter) {
        Intent intent = buildIntent(activity.getContext(), mThemeColor, maxSelection, selection, mediaTypeFilter);
        activity.startAbilityForResult(intent, requestCode);
    }

    /**
     * Start the Gallery Fragment with additional launch information.
     *
     * @param maxSelection    The max count of image selection
     * @param selection       The current image selection
     * @param mediaTypeFilter The media types that will display
     * @param mThemeColor     Color
     * @param context         Context
     * @return Intent
     */
    private static Intent buildIntent(Context context, int mThemeColor, int maxSelection, List<Uri> selection,
                                      String[] mediaTypeFilter) {
        Intent intent = new Intent();
        Operation operation = new Intent.OperationBuilder()
                .withBundleName(context.getBundleName())
                .withAbilityName(GalleryFragment.class.getName())
                .build();
        intent.setOperation(operation);

        intent.setParam(EXTRA_THEME_COLOR, mThemeColor);
        if (maxSelection > 0) {
            intent.setParam(EXTRA_MAX_SELECTION, maxSelection);
        }
        if (selection != null) {
            intent.setParam(EXTRA_SELECTION, new LinkedList<>(selection));
        }
        if (mediaTypeFilter != null && mediaTypeFilter.length > 0) {
            intent.setParam(EXTRA_MEDIA_TYPE_FILTER, mediaTypeFilter);
        } else {
            intent.setParam(EXTRA_MEDIA_TYPE_FILTER, new String[]{});
        }
        return intent;
    }

    /**
     * DEFAULT_MAX_SELECTION
     */
    private static final int DEFAULT_MAX_SELECTION = 1;
    /**
     * DEFAULT_THEME_COLOR
     */
    private static final int DEFAULT_THEME_COLOR = 0;
    private Component mEmptyView;
    private TableLayoutManager mLayoutManager;
    private ListContainer mRecyclerView;
    private GalleryFragmentAdapter mGalleryImagesAdapter = null;
    private List<Uri> mImages = new ArrayList<>();
    private ResultSetLoader mMediaLoader;
    private Button mFab;
    private int mThemeColor;
    private StackLayout toolBarLayout;
    GalleryAdapter.Callbacks mCallBack = new GalleryAdapter.Callbacks() {
        @Override
        public void onBucketClick(long bucketId, String label) {
        }

        @Override
        public void onMediaClick(Component imageView, Component checkView, long bucketId, int position) {
            PreviewActivity.startActivity2(GalleryFragment.this, PREVIEW_REQUEST_CODE,
                    getIntent().getIntParam(EXTRA_THEME_COLOR, DEFAULT_THEME_COLOR),
                    imageView, checkView,
                    bucketId, position, mGalleryImagesAdapter.getSelection(),
                    getIntent().getIntParam(EXTRA_MAX_SELECTION, DEFAULT_MAX_SELECTION),
                    mImages,
                    getIntent().getStringArrayParam(EXTRA_MEDIA_TYPE_FILTER));
        }

        @Override
        public void onSelectionUpdated(int count) {
            if (count != 0) {
                mFab.setText("Done (" + count + ")");
            } else {
                mFab.setText("Done");
            }
        }

        @Override
        public void onMaxSelectionReached() {
            new ToastDialog(getContext()).setText(Utils.getString(getContext(),
                    ResourceTable.String_activity_gallery_will_exceed_max_selection)).show();
        }

        @Override
        public void onWillExceedMaxSelection() {
            new ToastDialog(getContext()).setText(Utils.getString(getContext(),
                    ResourceTable.String_activity_gallery_will_exceed_max_selection)).show();
        }
    };

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_fragment_gallery);
        mThemeColor = getIntent().getIntParam(EXTRA_THEME_COLOR, 0);

        mMediaLoader = new ResultSetLoader(this);
        mGalleryImagesAdapter = new GalleryFragmentAdapter(getContext(), mCallBack, mImages);
        mGalleryImagesAdapter.setMaxSelection(getIntent().getIntParam(EXTRA_MAX_SELECTION, DEFAULT_MAX_SELECTION));
        mGalleryImagesAdapter.setSelection((List<Uri>) getIntent().getSerializableParam(EXTRA_SELECTION));
        mMediaLoader.setSelectionArgsForSingleMediaType(getIntent().getStringArrayParam(EXTRA_MEDIA_TYPE_FILTER));

        toolBarLayout = (StackLayout) findComponentById(ResourceTable.Id_toolBarLayout);
        if (mThemeColor == 0) {
            getWindow().setStatusBarColor(Utils.getColor(getContext(), ResourceTable.Color_default_theme_color));
        } else {
            getWindow().setStatusBarColor(Utils.getColor(getContext(), mThemeColor));
            ShapeElement element = new ShapeElement();
            element.setRgbColor(RgbColor.fromArgbInt(Utils.getColor(getContext(),
                    mThemeColor)));
            toolBarLayout.setBackground(element);
        }
        mEmptyView = findComponentById(ResourceTable.Id_empty);
        mLayoutManager = new TableLayoutManager();
        mLayoutManager.setColumnCount(4);
        mRecyclerView = (ListContainer) findComponentById(ResourceTable.Id_list_container);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setItemProvider(mGalleryImagesAdapter);
        CheckRadioView checkAll = (CheckRadioView) findComponentById(ResourceTable.Id_checkAll);
        checkAll.setChecked(true);
        CheckRadioView clearAll = (CheckRadioView) findComponentById(ResourceTable.Id_clearAll);
        checkAll.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                mGalleryImagesAdapter.selectAll();
            }
        });
        clearAll.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                mGalleryImagesAdapter.clearSelection();
            }
        });
        mFab = (Button) findComponentById(ResourceTable.Id_fab_done);
        mFab.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                Intent data = new Intent();
                data.setParam(EXTRA_SELECTION, new LinkedList<>(mGalleryImagesAdapter.getSelection()));
                setResult(RESULT_OK, data);
                onBackPressed();
            }
        });
        onAlbumSelected("All Media");
    }

    private Uri getData(ResultSet mData) {
        int id = mData.getInt(mData.getColumnIndexForName(AVStorage.Images.Media.ID));
        Uri uri = Uri.appendEncodedPathToUri(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, String.valueOf(id));
        return uri;
    }

    private void onAlbumSelected(String label) {
        mMediaLoader.setLoaderCallback(new LoaderCallback<ResultSet>() {
            @Override
            public void setCallback(ResultSet resultSet) {
                ArrayList<Uri> images = new ArrayList<>();
                if (resultSet.goToFirstRow()) {
                    do {
                        if (!"All Media".equals(label)) {
                            String data = resultSet.getString(resultSet
                                    .getColumnIndexForName(AVStorage.AVBaseColumns.DATA));
                            int last = data.lastIndexOf("/");
                            if (last >= 0) {
                                String lastString = data.substring(0, last);

                                int last2 = lastString.lastIndexOf("/");
                                String lastString2 = lastString.substring(last2 + 1);
                                if (label.equals(lastString2)) {
                                    images.add(getData(resultSet));
                                }
                            }
                        } else {
                            images.add(getData(resultSet));
                        }
                    } while (resultSet.goToNextRow());
                }
                mImages.clear();
                mImages.addAll(images);
                mRecyclerView.setItemProvider(mGalleryImagesAdapter);
                resultSet.close();
                updateEmptyState(mGalleryImagesAdapter);
            }
        });
        mMediaLoader.load();
    }

    private void updateEmptyState(BaseItemProvider mAdapter) {
        mRecyclerView.setVisibility(mAdapter.getCount() > 0 ? Component.VISIBLE : Component.INVISIBLE);
        mEmptyView.setVisibility(mAdapter.getCount() > 0 ? Component.INVISIBLE : Component.VISIBLE);
    }

    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
        if (requestCode == PREVIEW_REQUEST_CODE && resultCode == RESULT_OK) {
            List<Uri> selection = (List<Uri>) resultData.getSerializableParam(EXTRA_SELECTION);
            mGalleryImagesAdapter.setSelection(selection);
            mGalleryImagesAdapter.notifyDataChanged();
        } else {
            super.onAbilityResult(requestCode, resultCode, resultData);
        }
    }
}
